home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / LIBRARY / PCTV3N3 / PTRMATH.PAS < prev    next >
Pascal/Delphi Source File  |  1991-10-14  |  4KB  |  95 lines

  1. unit ptrmath;
  2. {*************************************************************
  3. * A unit of functions for directly manipulating TP pointers. *
  4. * Requires a version of TP with the built-in assembler.      *
  5. * (C) Daniel A. Bronstein, Michigan State University, 1991.  *
  6. *     May be freely used provided attribution is made.       *
  7. *************************************************************}
  8.  
  9. Interface
  10.  
  11. function ptrinc(p:pointer;w:word):pointer;
  12. function ptrdec(p:pointer;w:word):pointer;
  13. function baseptr(p:pointer):pointer;
  14.  
  15. Implementation
  16.  
  17. {************************************
  18. * PTRINC - Inc a pointer by a word. *
  19. ************************************}
  20. function ptrinc(p:pointer;w:word):pointer;assembler;
  21. asm
  22.   les   di,p                    {Load pointer in ES:DI and}
  23.   mov   bx,di                   {save DI in BX for later use.}
  24.   add   di,w                    {Add w to DI and see if we}
  25.   cmp   di,bx                   {have wrapped around.}
  26.   ja    @xit                    {If not, all ok, so exit, else}
  27.   xor   di,di                   {return a nil pointer by 0'ing}
  28.   mov   es,di                   {DI and ES.}
  29. @xit:
  30.   mov   ax,di                   {Return the pointer in}
  31.   mov   dx,es                   {DX:AX.}
  32. end;
  33.  
  34. {************************************
  35. * PTRDEC - Dec a pointer by a word. *
  36. ************************************}
  37. function ptrdec(p:pointer;w:word):pointer;assembler;
  38. asm
  39.   les   di,p                           {Same system as PTRINC.}
  40.   mov   bx,di
  41.   sub   di,w
  42.   cmp   di,bx
  43.   jb    @xit
  44.   xor   di,di
  45.   mov   es,di
  46. @xit:
  47.   mov   ax,di
  48.   mov   dx,es
  49. end;
  50.  
  51. {*******************************************************************
  52. * BASEPTR - Create a base pointer - Return pointer in the form     *
  53. * $XXXX:$000X; e.g., $66F3:$800A = $6EF3:$000A.  This is very      *
  54. * useful as some versions of DOS on some machines may not always   *
  55. * return allocated memory in this format, which allows for easy    *
  56. * wrap-around checks in PTRINC and PTRDEC. Does not work if the    *
  57. * original segment is greater than $F000 as it might itself        *
  58. * wrap-around in that case, but since TP cannot allocate memory in *
  59. * the $F000 segment that should not be a problem.                  *
  60. * Algorithm is:                                                    *
  61. *   power = 12                                                     *
  62. *   divr = 2^power                                                 *
  63. *   while offset > 16                                              *
  64. *     quot = offset / divr                                         *
  65. *     offset = offset - (quot * divr)                              *
  66. *     power = power - 4                                            *
  67. *     divr = 2^power                                               *
  68. *     segment = segment + (quot * divr)                            *
  69. *******************************************************************}
  70.  
  71. function baseptr(p:pointer):pointer;assembler;
  72. asm
  73.   les   di,p                      {Load the ptr and}
  74.   mov   dx,es                     {move ES to DX.}
  75.   cmp   dx,0F000h                 {If ES(DX) > $F000, danger of}
  76.   ja    @xit                      {wrap-around, so exit.}
  77.   mov   cl,12                     {Prepare CL for SHL & SHR.}
  78. @loop:
  79.   cmp   di,10h                    {If DI < 16 then done,}
  80.   jb    @xit                      {so exit;}
  81.   mov   ax,di                     {Move DI to AX and}
  82.   shr   ax,cl                     {divide by 2^CL (4096,256,16),}
  83.   mov   bx,ax                     {move AX to BX and}
  84.   shl   bx,cl                     {multiply by 2^CL then}
  85.   sub   di,bx                     {subtract from DI.}
  86.   sub   cl,4                      {Reduce CL by 4,}
  87.   shl   ax,cl                     {multiply AX by 2^CL}
  88.   add   dx,ax                     {and add it to DX,}
  89.   jmp   @loop                     {then loop back.}
  90. @xit:
  91.   mov   ax,di                     {Return the ptr in DX:AX.}
  92. end;
  93.  
  94. end.
  95.